Telegram Group & Telegram Channel
🐹 Задача с подвохом: Generics и интерфейсы (Go 1.24)

Условие:

Что выведет следующий код и почему?


package main

import (
"fmt"
)

type Stringer interface {
String() string
}

type MyInt int

func (m MyInt) String() string {
return fmt.Sprintf("MyInt: %d", m)
}

func printValue[T any](val T) {
var s Stringer
if v, ok := any(val).(Stringer); ok {
s = v
}
if s != nil {
fmt.Println("Stringer:", s.String())
} else {
fmt.Println("Default:", val)
}
}

func main() {
var x MyInt = 5
printValue(x)
printValue(10)
}


Вопрос:
Что будет напечатано? Почему результат может удивить даже опытных Go-разработчиков?

🔍 Разбор:

Этот код использует generics и проверяет, реализует ли
val интерфейс Stringer.

Пошагово:

1️⃣
var x MyInt = 5
Тип
MyInt реализует интерфейс Stringer через метод:

```go
func (m MyInt) String() string { ... }
```

2️⃣
printValue(x)
-
val здесь типа MyInt.
- В строке:
any(val).(Stringer)
- Приведение типа успешно, потому что
MyInt реализует Stringer.
- Печатается:
```
Stringer: MyInt: 5
```

3️⃣
printValue(10)
- Тип
val здесь int.
-
int не реализует Stringer.
- Приведение
any(val).(Stringer) не срабатывает (ok == false).
- Печатается:
```
Default: 10
```

Ожидаемый вывод:

```
Stringer: MyInt: 5
Default: 10
```

💥 Подвох:

- Даже если
MyInt — это просто int, метод String() делает его другим типом, который реализует интерфейс.
- Многие забывают, что встроенные типы (int, string, и т.д.) никогда не реализуют интерфейсы напрямую, даже если они похожи на пользовательские типы.
- Ключевой момент:
any(val) оборачивает значение в интерфейс{}, поэтому приведение типа срабатывает только если исходный тип действительно реализует интерфейс.

🆕 Почему это актуально для Go 1.24:

Generics в Go 1.22+ улучшились по типовой проверке и стали более гибкими. Go 1.24 сделал generics более стабильными и оптимизированными, но все еще важно понимать различия между типами и интерфейсами, особенно при работе с
any и приведения типов внутри параметризованных функций.

🛡️ Лайфхак:

Если вы хотите печатать всё одинаково для типов с
String(), можно сделать generic-констрейн с интерфейсом:

```go
func printValue2[T fmt.Stringer](val T) {
fmt.Println("Stringer (generic):", val.String())
}
```

Вывод:

Generics упрощают код, но внимательность к типам и их интерфейсам критически важна. Даже небольшие различия между
int и MyInt влияют на поведение программы.



tg-me.com/golangtests/773
Create:
Last Update:

🐹 Задача с подвохом: Generics и интерфейсы (Go 1.24)

Условие:

Что выведет следующий код и почему?


package main

import (
"fmt"
)

type Stringer interface {
String() string
}

type MyInt int

func (m MyInt) String() string {
return fmt.Sprintf("MyInt: %d", m)
}

func printValue[T any](val T) {
var s Stringer
if v, ok := any(val).(Stringer); ok {
s = v
}
if s != nil {
fmt.Println("Stringer:", s.String())
} else {
fmt.Println("Default:", val)
}
}

func main() {
var x MyInt = 5
printValue(x)
printValue(10)
}


Вопрос:
Что будет напечатано? Почему результат может удивить даже опытных Go-разработчиков?

🔍 Разбор:

Этот код использует generics и проверяет, реализует ли
val интерфейс Stringer.

Пошагово:

1️⃣
var x MyInt = 5
Тип
MyInt реализует интерфейс Stringer через метод:

```go
func (m MyInt) String() string { ... }
```

2️⃣
printValue(x)
-
val здесь типа MyInt.
- В строке:
any(val).(Stringer)
- Приведение типа успешно, потому что
MyInt реализует Stringer.
- Печатается:
```
Stringer: MyInt: 5
```

3️⃣
printValue(10)
- Тип
val здесь int.
-
int не реализует Stringer.
- Приведение
any(val).(Stringer) не срабатывает (ok == false).
- Печатается:
```
Default: 10
```

Ожидаемый вывод:

```
Stringer: MyInt: 5
Default: 10
```

💥 Подвох:

- Даже если
MyInt — это просто int, метод String() делает его другим типом, который реализует интерфейс.
- Многие забывают, что встроенные типы (int, string, и т.д.) никогда не реализуют интерфейсы напрямую, даже если они похожи на пользовательские типы.
- Ключевой момент:
any(val) оборачивает значение в интерфейс{}, поэтому приведение типа срабатывает только если исходный тип действительно реализует интерфейс.

🆕 Почему это актуально для Go 1.24:

Generics в Go 1.22+ улучшились по типовой проверке и стали более гибкими. Go 1.24 сделал generics более стабильными и оптимизированными, но все еще важно понимать различия между типами и интерфейсами, особенно при работе с
any и приведения типов внутри параметризованных функций.

🛡️ Лайфхак:

Если вы хотите печатать всё одинаково для типов с
String(), можно сделать generic-констрейн с интерфейсом:

```go
func printValue2[T fmt.Stringer](val T) {
fmt.Println("Stringer (generic):", val.String())
}
```

Вывод:

Generics упрощают код, но внимательность к типам и их интерфейсам критически важна. Даже небольшие различия между
int и MyInt влияют на поведение программы.

BY Go tests


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/golangtests/773

View MORE
Open in Telegram


Go tests Telegram | DID YOU KNOW?

Date: |

Importantly, that investor viewpoint is not new. It cycles in when conditions are right (and vice versa). It also brings the ineffective warnings of an overpriced market with it.Looking toward a good 2022 stock market, there is no apparent reason to expect these issues to change.

How Does Bitcoin Work?

Bitcoin is built on a distributed digital record called a blockchain. As the name implies, blockchain is a linked body of data, made up of units called blocks that contain information about each and every transaction, including date and time, total value, buyer and seller, and a unique identifying code for each exchange. Entries are strung together in chronological order, creating a digital chain of blocks. “Once a block is added to the blockchain, it becomes accessible to anyone who wishes to view it, acting as a public ledger of cryptocurrency transactions,” says Stacey Harris, consultant for Pelicoin, a network of cryptocurrency ATMs. Blockchain is decentralized, which means it’s not controlled by any one organization. “It’s like a Google Doc that anyone can work on,” says Buchi Okoro, CEO and co-founder of African cryptocurrency exchange Quidax. “Nobody owns it, but anyone who has a link can contribute to it. And as different people update it, your copy also gets updated.”

Go tests from tw


Telegram Go tests
FROM USA